﻿#include "wnodemanager.h"
#include "../cmainframe.h"
#include "../common.h"
#include "crouteconditions.h"

initialiseSingleton(WNodeManager);

void tagSectNode::clearLock(void)
{
    std::map<int,wxVector<WBaseNode*>>::iterator iter = nodes.begin();
    for(;iter != nodes.end();++iter)
    {
        for(int i=0;i<(*iter).second.size();i++)
        {
            if((*iter).second[i]->getOperState() == NodeOperState::LOCKED)
                (*iter).second[i]->setOperState(NodeOperState::NORMAL);
        }
    }

    operstate = NodeOperState::NORMAL;
    WNodeManager::getSingleton().slot_processSwitchChangeToSect();
}

wxColour tagSectNode::getStateColor(void)
{
    wxColour decColour = wxColour(255,255,255,255);

    // 先判断操作条件
    switch(operstate)
    {
    case NodeOperState::CHOSEN:            // 选中
        decColour = wxColour(165, 42, 42,255);
        break;
    case NodeOperState::LOCKED:            // 锁闭
        decColour = wxColour(0, 255, 0,255);
        break;
    default:
        break;
    }

    // 信号条件
    switch(signalstate)
    {
    case NodeSignalState::OCCUPY:             // 占用
        decColour = wxColour(255, 0, 0,255);
        break;
    case NodeSignalState::NOSIGNAL:           // 没信号
        decColour = wxColour(255, 255, 0,255);
        break;
    default:
        break;
    }

    return decColour;
}

// 检测进路是否在区段中
int tagSectNode::isInSect(wxVector<tagSLRouteNode>& decnodes,int *startPosition)
{
    if(decnodes.empty() ||
        nodes.empty())
        return -1;

    std::map<int,wxVector<WBaseNode*>>::iterator iter = nodes.begin();
    for(;iter != nodes.end();++iter)
    {
        if((*iter).second.empty())
            continue;

        int index = *startPosition;
        bool isOk = true;

        for(int k=0;k<(*iter).second.size();k++)
        {
            if(index >= decnodes.size() ||
               decnodes[index].node != (*iter).second[k])
            {
                isOk = false;
                break;
            }

            index+=1;
        }

        if(isOk)
        {
            // 越过中间的挂接点
            for(int i=index;i<decnodes.size();i++)
            {
                if(decnodes[i].node->getNodeType() != NodeType::NODE_MOUNT)
                {
                    index = i;
                    break;
                }
            }

            *startPosition = index;
            return (*iter).first;
        }
    }

    return -1;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

WNodeManager::WNodeManager()
{

}

WNodeManager::~WNodeManager()
{
    deleteAllNodes();
}

/// 保存json配置
bool WNodeManager::saveJsonConfig(wxString configfilepath)
{
    if(configfilepath == "")
        configfilepath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath() + "\\resources\\scripts\\站场配置.lua";

    wxString stationConfigString;

    // 创建 cJSON 对象
    cJSON *root = cJSON_CreateObject();

    cJSON *nodes = cJSON_CreateArray();
    std::map<wxString,WBaseNode*> allnodes = WNodeManager::getSingleton().getAllNodes();
    std::map<wxString,WBaseNode*>::iterator iter = allnodes.begin();
    for(;iter != allnodes.end();++iter)
    {
        cJSON *node = cJSON_CreateObject();
        cJSON_AddNumberToObject(node, "nodetype", (int)(*iter).second->getNodeType());
        cJSON_AddStringToObject(node, "nodename", (*iter).second->getName());
        cJSON *position = cJSON_AddObjectToObject(node, "position");
        cJSON_AddNumberToObject(position, "x", (*iter).second->getPosition().x);
        cJSON_AddNumberToObject(position, "y", (*iter).second->getPosition().y);

        switch((*iter).second->getNodeType())
        {
        case NodeType::NODE_SIGNAL:
        {
            WSignalLampNode *pWSignalLampNode = static_cast<WSignalLampNode*>((*iter).second);
            if(pWSignalLampNode)
            {
                cJSON_AddNumberToObject(node, "direction", (int)pWSignalLampNode->getNameAlignment());
                cJSON_AddNumberToObject(node, "routetype", (int)pWSignalLampNode->getRouteType());
            }
        }
            break;
        case NodeType::NODE_SWITCH:
        {
            WSwitchNode *pWSwitchNode = static_cast<WSwitchNode*>((*iter).second);
            if(pWSwitchNode)
            {
                wxString decString;
                std::map<SwitchState,SwitchStateMounts> mounts = pWSwitchNode->getAllSwitchStateMounts();
                std::map<SwitchState,SwitchStateMounts>::iterator iter2 = mounts.begin();
                for(;iter2 != mounts.end();++iter2)
                {
                    decString += wxString::Format("%d:%s-%s;",
                                                  (*iter2).first,
                                                  (*iter2).second.startMount->name,
                                                  (*iter2).second.endMount->name);
                }

                if(decString != "") decString = decString.Mid(0,decString.size()-1);

                cJSON_AddStringToObject(node, "switchstate", decString);
            }
        }
            break;
        default:
            break;
        }

        cJSON_AddItemToArray(nodes, node);
    }
    cJSON_AddItemToObject(root, "nodes", nodes);

    cJSON *mountpointsArr = cJSON_CreateArray();
    allnodes = WNodeManager::getSingleton().getAllNodes();
    iter = allnodes.begin();
    for(;iter != allnodes.end();++iter)
    {
        std::map<wxString,tagMountPoint> mountpoints = (*iter).second->getAllMountPoints();

        if(!mountpoints.empty())
        {
            std::map<wxString,tagMountPoint>::iterator itermount = mountpoints.begin();

            cJSON *mount = cJSON_CreateObject();
            cJSON_AddStringToObject(mount, "nodename", (*iter).second->getName());
            cJSON *mounts = cJSON_CreateArray();

            for(;itermount != mountpoints.end();++itermount)
            {
                cJSON *mountobj = cJSON_CreateObject();
                cJSON_AddStringToObject(mountobj, "mountname", (*itermount).second.name);
                cJSON_AddStringToObject(mountobj, "mountnode", (*itermount).second.node->getName());
                cJSON *position = cJSON_AddObjectToObject(mountobj, "mountpos");
                cJSON_AddNumberToObject(position, "x", (*itermount).second.pos.x);
                cJSON_AddNumberToObject(position, "y", (*itermount).second.pos.y);
                cJSON_AddNumberToObject(mountobj, "level", (*itermount).second.level);
                cJSON_AddNumberToObject(mountobj, "orientation", (*itermount).second.direction);

                cJSON_AddItemToArray(mounts, mountobj);
            }

            cJSON_AddItemToObject(mount, "mounts", mounts);
            cJSON_AddItemToArray(mountpointsArr, mount);
        }
    }
    cJSON_AddItemToObject(root, "mountpoints", mountpointsArr);

    cJSON *sects = cJSON_CreateArray();

    std::map<wxString,tagSectNode*> allsects = WNodeManager::getSingleton().getAllSects();
    std::map<wxString,tagSectNode*>::iterator itersect = allsects.begin();
    for(;itersect != allsects.end();++itersect)
    {
        cJSON *sectobj = cJSON_CreateObject();
        cJSON_AddStringToObject(sectobj, "sectname", (*itersect).first);

        wxString decrange;
        std::map<int,wxVector<WBaseNode*>>::iterator itersectnodes = (*itersect).second->nodes.begin();
        for(;itersectnodes != (*itersect).second->nodes.end();++itersectnodes)
        {
            if((*itersectnodes).second.size() > 1)
                decrange += wxString::Format("%s-%s;",(*itersectnodes).second[0]->getName(),
                                             (*itersectnodes).second[(*itersectnodes).second.size()-1]->getName());
        }

        if(!decrange.IsEmpty())
            decrange = decrange.Mid(0,decrange.size()-1);
        cJSON_AddStringToObject(sectobj, "range", decrange);

        wxString lastsect;
        for(int i=0;i<(*itersect).second->lastsects.size();i++)
        {
            lastsect += wxString::Format("%s;",(*itersect).second->lastsects[i]);
        }

        if(!lastsect.IsEmpty()) lastsect = lastsect.Mid(0,lastsect.size()-1);
        cJSON_AddStringToObject(sectobj, "lastsect", lastsect);

        wxString nextsect;
        for(int i=0;i<(*itersect).second->nextsects.size();i++)
        {
            nextsect += wxString::Format("%s;",(*itersect).second->nextsects[i]);
        }

        if(!nextsect.IsEmpty()) nextsect = nextsect.Mid(0,nextsect.size()-1);
        cJSON_AddStringToObject(sectobj, "nextsect", nextsect);

        cJSON_AddItemToArray(sects, sectobj);
    }

    cJSON_AddItemToObject(root, "sects", sects);

    cJSON *routecondi = cJSON_CreateArray();

    std::map<wxString,std::map<wxString,tagRouteCondiItem>> allrouteconditions = CRouteConditions::getSingleton().getAllRouteConditions();
    std::map<wxString,std::map<wxString,tagRouteCondiItem>>::iterator itercondition = allrouteconditions.begin();
    for(;itercondition != allrouteconditions.end();++itercondition)
    {
        cJSON *routecondition = cJSON_CreateObject();

        std::map<wxString,tagRouteCondiItem>::iterator iterconditionitem = (*itercondition).second.begin();
        for(;iterconditionitem != (*itercondition).second.end();++iterconditionitem)
        {
            cJSON_AddStringToObject(routecondition, "startlight", (*itercondition).first);
            cJSON_AddStringToObject(routecondition, "endlight", (*iterconditionitem).first);
            cJSON *conflictsignals = cJSON_CreateArray();

            for(int i=0;i<(*iterconditionitem).second.conflictsignals.size();i++)
                cJSON_AddItemToArray(conflictsignals, cJSON_CreateString((*iterconditionitem).second.conflictsignals[i]->getName()));

            cJSON_AddItemToObject(routecondition, "conflictsignal", conflictsignals);

            cJSON *conflictswitchs = cJSON_CreateArray();

            for(int i=0;i<(*iterconditionitem).second.conflictswitch.size();i++)
            {
                cJSON *conflictswitchobj = cJSON_CreateObject();
                cJSON_AddStringToObject(conflictswitchobj,
                                        (*iterconditionitem).second.conflictswitch[i].switchnode->getName(),
                                        (*iterconditionitem).second.conflictswitch[i].switchstate == SwitchState::POSITIVE ? "定位" : "反位");

                cJSON_AddItemToArray(conflictswitchs, conflictswitchobj);
            }

            cJSON_AddItemToObject(routecondition, "conflictswitch", conflictswitchs);

            cJSON *followswitchs = cJSON_CreateArray();

            for(int i=0;i<(*iterconditionitem).second.followswitch.size();i++)
            {
                cJSON *followswitchobj = cJSON_CreateObject();
                cJSON_AddStringToObject(followswitchobj,
                                        (*iterconditionitem).second.followswitch[i].switchnode->getName(),
                                        (*iterconditionitem).second.followswitch[i].switchstate == SwitchState::POSITIVE ? "定位" : "反位");

                cJSON_AddItemToArray(followswitchs, followswitchobj);
            }

            cJSON_AddItemToObject(routecondition, "followswitch", followswitchs);
        }

        cJSON_AddItemToArray(routecondi, routecondition);
    }

    cJSON_AddItemToObject(root, "routecondi", routecondi);

    // 将 cJSON 对象转换为字符串
    char *json_string = cJSON_Print(root);
    if (json_string) {

        stationConfigString = wxString::Format("stationConfig = [[%s]];",json_string);

        // 释放字符串内存
        free(json_string);
    }

    // 释放 cJSON 对象内存
    cJSON_Delete(root);

    wxFile file(configfilepath, wxFile::write);
    if (file.IsOpened())
    {
        wxCSConv gb2312Conv(wxFONTENCODING_CP936);
        wxCharBuffer buffer = gb2312Conv.cWC2MB(stationConfigString.wc_str());

        if (buffer.data()) {
            file.Write(buffer.data(), strlen(buffer.data()));
        }

        file.Close();
    }

    return true;
}

bool WNodeManager::loadJsonConfig(const char* configstr)
{
    if(configstr == "") return false;

    // 先清空所有数据
    this->clear();

    // 解析 JSON 字符串
    cJSON *doc = cJSON_Parse(configstr);
    if (!doc) {
        const char *error_ptr = cJSON_GetErrorPtr();
        wxString pErrorStr = wxString::Format(wxT("JSON 解析失败: "
                                                  "错误位置: %s"),
                                             error_ptr ? error_ptr : "未知");
        CMainFrame::getSingleton().printlog(LOG_LEVEL_ERROR, pErrorStr.ToUTF8());
        return false;
    }

    wxMutexLocker locker(mNodeMutex);

    // 获取根对象
    cJSON *root = doc;
    std::vector<wxString> decfiles;
    std::map<WBaseNode*,std::map<SwitchState,tagSwitchRoute>> tmpSwitchRoutes;
    wxCSConv gb2312Conv(wxFONTENCODING_UTF8);

    // 获取所有的结点
    cJSON *nodes = cJSON_GetObjectItemCaseSensitive(root, "nodes");
    if (nodes && cJSON_IsArray(nodes)) {
        cJSON *node_item = NULL;
        cJSON_ArrayForEach(node_item, nodes) {
            cJSON *nodenameval = cJSON_GetObjectItemCaseSensitive(node_item, "nodename");
            cJSON *nodetypeval = cJSON_GetObjectItemCaseSensitive(node_item, "nodetype");
            cJSON *positionval = cJSON_GetObjectItemCaseSensitive(node_item, "position");
            cJSON *directionval = cJSON_GetObjectItemCaseSensitive(node_item, "direction");
            cJSON *defaultrouteval = cJSON_GetObjectItemCaseSensitive(node_item, "switchstate");
            cJSON *routetypeval = cJSON_GetObjectItemCaseSensitive(node_item, "routetype");
            cJSON *deviceid = cJSON_GetObjectItemCaseSensitive(node_item, "deviceid");

            if (!nodenameval || !nodetypeval || !positionval) {
                continue;  // 跳过无效的结点
            }

            NodeType pNodeType = (NodeType)static_cast<int>(cJSON_GetNumberValue(nodetypeval));
            wxString pNodeName = wxString(cJSON_GetStringValue(nodenameval));

            cJSON *positionXval = cJSON_GetObjectItemCaseSensitive(positionval, "x");
            cJSON *positionYval = cJSON_GetObjectItemCaseSensitive(positionval, "y");

            if (!positionXval || !positionYval) {
                continue;  // 跳过无效的位置数据
            }

            wxRealPoint pNodePosition = wxRealPoint(
                cJSON_GetNumberValue(positionXval),
                cJSON_GetNumberValue(positionYval)
            );

            decfiles.push_back(pNodeName);

            switch (pNodeType)
            {
            case NODE_MOUNT:     // 挂接点
            {
                WMountNode* pMountNode = this->addMountNode(pNodeName, pNodePosition);
                if(pMountNode != NULL)
                {
                    //pMountNode->setDeviceID(deviceid != NULL ? cJSON_GetNumberValue(deviceid) : this->getAllNodes().size());
                }
            }
                break;
            case NODE_SIGNAL:    // 信号灯
            {
                WSignalLampNode* pSignalLampNode = this->addSignalLamp(pNodeName, pNodePosition);
                if(pSignalLampNode != NULL &&
                   directionval != NULL &&
                   routetypeval != NULL)
                {
                    pSignalLampNode->setNameAlignment((TextAlignment)static_cast<int>(cJSON_GetNumberValue(directionval)));
                    pSignalLampNode->setRouteType((SLRouteType)static_cast<int>(cJSON_GetNumberValue(routetypeval)));
                    pSignalLampNode->setDeviceID(deviceid != NULL ? cJSON_GetNumberValue(deviceid) : this->getAllNodes().size());
                }
            }
                break;
            case NODE_SWITCH:    // 道岔
            {
                WSwitchNode* pSwitchNode = this->addSwitch(pNodeName, pNodePosition);
                if(pSwitchNode != NULL && defaultrouteval != NULL)
                {
                    wxArrayString paramarray = SplitString(wxString(cJSON_GetStringValue(defaultrouteval),gb2312Conv),
                                                           ";");
                    for(int k=0;k<paramarray.size();k++)
                    {
                        wxArrayString paramarray1 = SplitString(paramarray[k],":");
                        if(paramarray1.size() == 2)
                        {
                            wxArrayString paramarray2 = SplitString(paramarray1[1],"-");

                            if(paramarray2.size() == 2)
                            {
                                int sState = 0;
                                if(paramarray1[0].ToInt(&sState))
                                    tmpSwitchRoutes[pSwitchNode][(SwitchState)sState] = tagSwitchRoute(paramarray2[0],paramarray2[1]);
                            }
                        }
                    }

                    pSwitchNode->setDeviceID(deviceid != NULL ? cJSON_GetNumberValue(deviceid) : this->getAllNodes().size());
                }
            }
                break;
            default:
                break;
            }
        }
    }

    // 获取所有的挂载点
    cJSON *mountpoints = cJSON_GetObjectItemCaseSensitive(root, "mountpoints");
    if (mountpoints && cJSON_IsArray(mountpoints)) {
        cJSON *mount_item = NULL;
        cJSON_ArrayForEach(mount_item, mountpoints) {
            cJSON *nodenameval = cJSON_GetObjectItemCaseSensitive(mount_item, "nodename");
            if (!nodenameval) {
                continue;
            }

            WBaseNode *psrcBaseNode = this->getNodeByName(wxString(cJSON_GetStringValue(nodenameval)));
            if (psrcBaseNode != NULL) {
                // 得到这个结点的所有挂载点
                cJSON *mounts = cJSON_GetObjectItemCaseSensitive(mount_item, "mounts");
                if (mounts && cJSON_IsArray(mounts)) {
                    cJSON *mount_val = NULL;
                    cJSON_ArrayForEach(mount_val, mounts) {
                        cJSON *mountnameval = cJSON_GetObjectItemCaseSensitive(mount_val, "mountname");
                        cJSON *mountnodeval = cJSON_GetObjectItemCaseSensitive(mount_val, "mountnode");
                        cJSON *levelval = cJSON_GetObjectItemCaseSensitive(mount_val, "level");
                        cJSON *orientationval = cJSON_GetObjectItemCaseSensitive(mount_val, "orientation");
                        cJSON *mountposval = cJSON_GetObjectItemCaseSensitive(mount_val, "mountpos");

                        if (!mountnameval || !mountnodeval || !levelval || !orientationval || !mountposval) {
                            continue;  // 跳过无效的挂载点
                        }

                        WBaseNode *pMountBaseNode = this->getNodeByName(wxString(cJSON_GetStringValue(mountnodeval)));
                        if (pMountBaseNode != NULL) {
                            cJSON *mountposXval = cJSON_GetObjectItemCaseSensitive(mountposval, "x");
                            cJSON *mountposYval = cJSON_GetObjectItemCaseSensitive(mountposval, "y");

                            if (!mountposXval || !mountposYval) {
                                continue;  // 跳过无效的位置数据
                            }

                            wxString pmountname = wxString(cJSON_GetStringValue(mountnameval),gb2312Conv);
                            int level = (int)cJSON_GetNumberValue(levelval);
                            MountDirection orientation = (MountDirection)static_cast<int>(cJSON_GetNumberValue(orientationval));
                            wxRealPoint pmountpos = wxRealPoint(
                                cJSON_GetNumberValue(mountposXval),
                                cJSON_GetNumberValue(mountposYval)
                            );

                            psrcBaseNode->addMountPoint(
                                pmountname,
                                tagMountPoint(pmountname,
                                              pmountpos,
                                              pMountBaseNode,
                                              level,
                                              orientation)
                            );
                        }
                    }
                }
            }
        }
    }

    // 获取所有的区段
    cJSON *sects = cJSON_GetObjectItemCaseSensitive(root, "sects");
    if (sects && cJSON_IsArray(sects)) {
        cJSON *sect_item = NULL;
        cJSON_ArrayForEach(sect_item, sects) {
            cJSON *sectnameval = cJSON_GetObjectItemCaseSensitive(sect_item, "sectname");
            if (!sectnameval) {
                continue;
            }

            tagSectNode *decSectNode = new tagSectNode();
            wxString sectname = wxString(cJSON_GetStringValue(sectnameval));

            cJSON *rangeval = cJSON_GetObjectItemCaseSensitive(sect_item, "range");

            wxArrayString paramarray1 = SplitString(wxString(cJSON_GetStringValue(rangeval),gb2312Conv),";");
            if(!paramarray1.empty())
            {
                std::map<int,wxVector<WBaseNode*>> decSectNodeParams;

                for(int k=0;k<paramarray1.size();k++)
                {
                    wxArrayString paramarray2 = SplitString(paramarray1[k],"-");
                    if(paramarray2.size() == 2)
                    {
                        wxVector<tagSLRouteNode> decroute = this->getRoute(paramarray2[0],paramarray2[1]);

                        for(int ii=0;ii<decroute.size();ii++)
                        {
                            decSectNodeParams[k].push_back(decroute[ii].node);
                        }
                    }
                }

                decSectNode->nodes = decSectNodeParams;
            }

            cJSON *deviceidval = cJSON_GetObjectItemCaseSensitive(sect_item, "deviceid");
            decSectNode->deviceID = (deviceidval != NULL ? cJSON_GetNumberValue(deviceidval) : -1);

            cJSON *lastsectval = cJSON_GetObjectItemCaseSensitive(sect_item, "lastsect");
            decSectNode->lastsects = SplitString(wxString(cJSON_GetStringValue(lastsectval)),";");
            cJSON *nextsectval = cJSON_GetObjectItemCaseSensitive(sect_item, "nextsect");
            decSectNode->nextsects = SplitString(wxString(cJSON_GetStringValue(nextsectval)),";");

            mSects[sectname] = decSectNode;
        }
    }

    // 获取所有的进路条件
    cJSON *routecondi = cJSON_GetObjectItemCaseSensitive(root, "routecondi");
    if (routecondi && cJSON_IsArray(routecondi)) {
        CRouteConditions::getSingleton().parsingJson(routecondi);
    }

    // 释放 JSON 文档
    cJSON_Delete(doc);

    // 最后删除不需要的脚本文件
    DeleteAllFilesInDir(wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath()+"\\resources\\scripts\\nodes",
                        decfiles);

    // 计算所有挂载点的角度
    computerStationNodeMountAngles();

    // 设置道岔的内部进路
    std::map<WBaseNode*,std::map<SwitchState,tagSwitchRoute>>::iterator iterswitch = tmpSwitchRoutes.begin();
    for(;iterswitch != tmpSwitchRoutes.end();++iterswitch)
    {
        WSwitchNode* pSwitchNode = static_cast<WSwitchNode*>((*iterswitch).first);
        if(pSwitchNode)
        {
            std::map<SwitchState,tagSwitchRoute>::iterator iterswitch2 = (*iterswitch).second.begin();
            for(;iterswitch2 != (*iterswitch).second.end();++iterswitch2)
            {
                pSwitchNode->initSwitchState((*iterswitch2).first,
                                            (*iterswitch2).second.startPos,
                                            (*iterswitch2).second.endPos);
            }
        }
    }

    /// 处理站场区段
    this->processStationSects();

    return true;
}

/// 设置结点的工作模式
void WNodeManager::setWorkingMode(WorkingMode mode)
{
    if(mNodes.empty()) return;

    wxMutexLocker locker(mNodeMutex);

    std::map<wxString,WBaseNode*>::iterator iter = mNodes.begin();
    for(;iter != mNodes.end();++iter)
    {
        (*iter).second->setWorkingMode(mode);
    }
}

/// 添加一个 信号灯
WSignalLampNode* WNodeManager::addSignalLamp(wxString nodeName,wxRealPoint pos)
{
    if(getNodeByName(nodeName) != NULL)
        return NULL;

    /*if((pos.x < 0 || pos.x > 100.0f) ||
       (pos.y < 0 || pos.y > 100.0f))
    {
        wxString perrString = wxString::Format("WNodeManager::addSignalLamp:%s:pos的值反正在0-100,"
                                               "不能超出这个范围:%f %f.",nodeName,pos.x,pos.y);
        CMainFrame::getSingleton().printlog(LOG_LEVEL_ERROR,perrString);
        return NULL;
    }*/

    WSignalLampNode *pSignalLampNode = new WSignalLampNode(nodeName);
    pSignalLampNode->setNodeManager(this);
    pSignalLampNode->setPosition(pos);

    /// 建立脚本文件
    pSignalLampNode->createScriptFile();

    mNodes[nodeName] = pSignalLampNode;

    return pSignalLampNode;
}

/// 添加一个道岔
WSwitchNode* WNodeManager::addSwitch(wxString nodeName,wxRealPoint pos)
{
    if(getNodeByName(nodeName) != NULL)
        return NULL;

    if((pos.x < 0 || pos.x > 100.0f) ||
       (pos.y < 0 || pos.y > 100.0f))
    {
        wxString perrString = wxString::Format(wxT("WNodeManager::addSwitch:%s:pos的值反正在0-100,"
                                                   "不能超出这个范围:%f %f."),nodeName,pos.x,pos.y);
        CMainFrame::getSingleton().printlog(LOG_LEVEL_ERROR,perrString.ToUTF8());
        return NULL;
    }

    WSwitchNode *pSwitchNode = new WSwitchNode(nodeName);
    pSwitchNode->setNodeManager(this);
    pSwitchNode->setPosition(pos);

    /// 建立脚本文件
    pSwitchNode->createScriptFile();

    mNodes[nodeName] = pSwitchNode;

    return pSwitchNode;
}

/// 添加一个挂接点
WMountNode* WNodeManager::addMountNode(wxString nodeName,wxRealPoint pos)
{
    if(getNodeByName(nodeName) != NULL)
        return NULL;

    if((pos.x < 0 || pos.x > 100.0f) ||
       (pos.y < 0 || pos.y > 100.0f))
    {
        wxString perrString = wxString::Format(wxT("WNodeManager::addMountNode:%s:pos的值反正在0-100,"
                                                   "不能超出这个范围:%f %f."),nodeName,pos.x,pos.y);
        CMainFrame::getSingleton().printlog(LOG_LEVEL_ERROR,perrString.ToUTF8());
        return NULL;
    }

    WMountNode *pMountNode = new WMountNode(nodeName);
    pMountNode->setNodeManager(this);
    pMountNode->setPosition(pos);

    mNodes[nodeName] = pMountNode;

    return pMountNode;
}

/// 得到指定坐标的结点
WBaseNode* WNodeManager::getNodeByPoint(wxPoint point)
{
    if(mNodes.empty()) return NULL;

    wxMutexLocker locker(mNodeMutex);

    std::map<wxString,WBaseNode*>::iterator iter = mNodes.begin();
    for(;iter != mNodes.end();++iter)
    {
        if((*iter).second->getBoundingRect().containsPoint(point))
            return (*iter).second;
    }

    return NULL;
}

/// 得到指定设备ID的结点
WBaseNode* WNodeManager::getNodeByDeviceID(int deviceid)
{
    wxMutexLocker locker(mNodeMutex);

    std::map<wxString,WBaseNode*>::iterator iter = mNodes.begin();
    for(;iter != mNodes.end();++iter)
    {
        if((*iter).second->getDeviceID() == deviceid)
            return (*iter).second;
    }

    return NULL;
}

/// 得到指定名称的结点
WBaseNode* WNodeManager::getNodeByName(wxString nodeName)
{
    wxMutexLocker locker(mNodeMutex);

    std::map<wxString,WBaseNode*>::iterator iter = mNodes.find(nodeName);
    if(iter == mNodes.end())
        return NULL;

    return (*iter).second;
}

/// 清除所有的数据
void WNodeManager::clear(void)
{
    // 先删除所有的结点
    this->deleteAllNodes();
}

/// 删除所有的结点
void WNodeManager::deleteAllNodes(void)
{
    wxMutexLocker locker(mNodeMutex);

    std::map<wxString,WBaseNode*>::iterator iter = mNodes.begin();
    for(;iter != mNodes.end();++iter)
    {
        delete (*iter).second;
        (*iter).second = NULL;
    }

    std::map<wxString,std::map<wxString,tagRoute*>>::iterator iter2 = mRoutes.begin();
    for(;iter2 != mRoutes.end();++iter2)
    {
        std::map<wxString,tagRoute*>::iterator iter3 = (*iter2).second.begin();
        for(;iter3 != (*iter2).second.end();++iter3)
        {
            delete (*iter3).second;
            (*iter3).second = NULL;
        }
    }

    std::map<wxString,tagSectNode*>::iterator itersect = mSects.begin();
    for(;itersect != mSects.end();++itersect)
    {
        delete (*itersect).second;
        (*itersect).second = NULL;
    }

    mNodes.clear();
    mSects.clear();
    mRoutes.clear();
    mdecSectNodes.clear();
}

/// 工作区域改变
void WNodeManager::changeWorkingRect(wxRect workingrect)
{
    if(mWorkingRect == workingrect) return;

    mWorkingRect = workingrect;

    wxMutexLocker locker(mNodeMutex);

    std::map<wxString,WBaseNode*>::iterator iter = mNodes.begin();
    for(;iter != mNodes.end();++iter)
        (*iter).second->changeWorkingRect(workingrect);

    // 计算所有挂载点的角度
    computerStationNodeMountAngles();
}

/// 计算站场所有结点挂载点的角度
void WNodeManager::computerStationNodeMountAngles(void)
{
    if(mNodes.empty()) return;

    std::map<wxString,WBaseNode*>::iterator iter = mNodes.begin();
    for(;iter != mNodes.end();++iter)
    {
        if((*iter).second->getNodeType() != NODE_SIGNAL)
            continue;

        // 右边的连接点
        wxVector<tagMountPoint> pRightPoints = (*iter).second->getMountPointByDir(DIRECTION_RIGHT);
        if(!pRightPoints.empty())
        {
            for(int i=0;i<pRightPoints.size();i++)
            {
                // 得到对应点的左边结点
                WBaseNode *pLeftNode = pRightPoints[i].node;

                tagMountPoint point;

                // 检测右边结点是否有挂接左边结点
                if(pLeftNode &&
                   pLeftNode->isExistMountNode((*iter).second,DIRECTION_LEFT,&point))
                {
                    wxRealPoint rightpos = pRightPoints[i].screenpos;
                    wxRealPoint leftpos = point.screenpos;

                    //pRightPoints[i].angle = CalculateAngle(rightpos,leftpos);
                    (*iter).second->setMountPointAngle(pRightPoints[i].name,
                                                       CalculateAngle(leftpos,rightpos));
                }
            }
        }

        // 左边的连接点
        wxVector<tagMountPoint> pLeftPoints = (*iter).second->getMountPointByDir(DIRECTION_LEFT);
        if(!pLeftPoints.empty())
        {
            for(int i=0;i<pLeftPoints.size();i++)
            {
                // 得到对应点的右边结点
                WBaseNode *pRightNode = pLeftPoints[i].node;

                tagMountPoint point;

                // 检测右边结点是否有挂接左边结点
                if(pRightNode &&
                   pRightNode->isExistMountNode((*iter).second,DIRECTION_RIGHT,&point))
                {
                    wxRealPoint leftpos = pLeftPoints[i].screenpos;
                    wxRealPoint rightpos = point.screenpos;

                    //pLeftPoints[i].angle = CalculateAngle(leftpos,rightpos);
                    (*iter).second->setMountPointAngle(pLeftPoints[i].name,
                                                       CalculateAngle(leftpos,rightpos));
                }
            }
        }
    }
}

/// 得到区段的名称
wxString WNodeManager::getSectName(WBaseNode* startNode,WBaseNode* endNode)
{
    std::map<wxString,tagSectNode>::iterator iter = mdecSectNodes.begin();
    for(;iter != mdecSectNodes.end();++iter)
    {
        std::map<int,wxVector<WBaseNode*>>::iterator iter2 = (*iter).second.nodes.begin();
        for(;iter2 != (*iter).second.nodes.end();++iter2)
        {
            auto it = std::find((*iter2).second.begin(),
                                (*iter2).second.end(),
                                startNode);
            auto it1 = std::find((*iter2).second.begin(),
                                 (*iter2).second.end(),
                                 endNode);
            if (it != (*iter2).second.end() &&
                it1 != (*iter2).second.end())
            {
                return (*iter).first;
            }
        }
    }

    return "";
}

/// 得到区段的颜色
wxColour WNodeManager::getSectColor(WBaseNode* startNode,WBaseNode* endNode)
{
    wxColour color(255,255,255,255);

    std::map<wxString,tagSectNode>::iterator iter = mdecSectNodes.begin();
    for(;iter != mdecSectNodes.end();++iter)
    {
        std::map<int,wxVector<WBaseNode*>>::iterator iter2 = (*iter).second.nodes.begin();
        for(;iter2 != (*iter).second.nodes.end();++iter2)
        {
            auto it = std::find((*iter2).second.begin(),
                                (*iter2).second.end(),
                                startNode);
            auto it1 = std::find((*iter2).second.begin(),
                                (*iter2).second.end(),
                                endNode);
            if (it != (*iter2).second.end() &&
                it1 != (*iter2).second.end())
            {
                return (*iter).second.getStateColor();
            }
        }
    }

    return color;
}

/// 设置指定区段的操作状态
void WNodeManager::setSectOperState(wxString sectName,int state)
{
    if(mSects.empty() || sectName == "")
        return;

    std::map<wxString,tagSectNode*>::iterator iter = mSects.find(sectName);
    if(iter == mSects.end())
        return;

    (*iter).second->operstate = (NodeOperState)state;

    this->slot_processSwitchChangeToSect();
}

/// 设置指定区段的信号状态
void WNodeManager::setSectSignalState(wxString sectName,int state)
{
    if(mSects.empty() || sectName == "")
        return;

    std::map<wxString,tagSectNode*>::iterator iter = mSects.find(sectName);
    if(iter == mSects.end())
        return;

    (*iter).second->lastsignalstate = (*iter).second->signalstate;
    (*iter).second->signalstate = (NodeSignalState)state;

    this->slot_processSwitchChangeToSect();
}

/// 处理道岔状态变化导致区段变化事件
void WNodeManager::slot_processSwitchChangeToSect(void)
{
    wxMutexLocker locker(mNodeMutex);

    /// 处理站场区段，得到区段占用情况
    this->processStationSects();
}

/// 处理站场区段，得到区段占用情况
void WNodeManager::processStationSects(void)
{
    if(mSects.empty()) return;

    mdecSectNodes.clear();

    std::map<wxString,tagSectNode*>::iterator iter = mSects.begin();
    for(;iter != mSects.end();++iter)
    {
        mdecSectNodes[(*iter).first] = *((*iter).second);

        // 处理道岔占用
        if((*iter).second->nodes.size() > 1)
        {
            bool isFinded = false;
            WBaseNode *pdecSwitch = NULL;
            std::map<int,wxVector<WBaseNode*>>::iterator iternode = (*iter).second->nodes.begin();
            for(;iternode != (*iter).second->nodes.end();++iternode)
            {
                for(int i=0;i<(*iternode).second.size();i++)
                {
                    if((*iternode).second[i]->getNodeType() == NodeType::NODE_SWITCH)
                    {
                        if(pdecSwitch != NULL && pdecSwitch == (*iternode).second[i])
                        {
                            WSwitchNode *pswitchnode = static_cast<WSwitchNode*>(pdecSwitch);
                            if(pswitchnode)
                            {
                                mdecSectNodes[(*iter).first].nodes.clear();
                                mdecSectNodes[(*iter).first].nodes[pswitchnode->getSwitchState()] = (*iter).second->nodes[pswitchnode->getSwitchState()];

                                // 设置区段中所有的道岔信号状态和区段一致
                                wxVector<WBaseNode*> decnodes = mdecSectNodes[(*iter).first].nodes[pswitchnode->getSwitchState()];
                                for(int k=0;k<decnodes.size();k++)
                                {
                                    if(decnodes[k]->getNodeType() == NodeType::NODE_SWITCH)
                                        decnodes[k]->setSignalState(mdecSectNodes[(*iter).first].signalstate);
                                }

                                isFinded = true;
                                break;
                            }
                        }

                        pdecSwitch = (*iternode).second[i];
                    }
                }

                if(isFinded)
                    break;
            }
        }
    }
}

/// 搜索两个结点之间的进路
std::list<tagSLRouteNode> WNodeManager::searchRoute(WBaseNode* startNode,WBaseNode* endNode,MountDirection md)
{
    std::list<tagSLRouteNode> pBaseNodeList;

    pBaseNodeList.push_front(tagSLRouteNode(startNode,0));

    while(!pBaseNodeList.empty())
    {
        tagSLRouteNode tmpBaseNode = pBaseNodeList.front();
        pBaseNodeList.pop_front();

        wxVector<tagMountPoint> pMountPoints = tmpBaseNode.node->getMountPointByDir(md);
        if(pMountPoints.empty())
            continue;

        int tmpindex=tmpBaseNode.MPointIndex;

        if(tmpindex >= pMountPoints.size())
            continue;

        tmpBaseNode.MPointIndex+=1;
        pBaseNodeList.push_front(tmpBaseNode);

        if(pMountPoints[tmpindex].node != endNode)
        {
            pBaseNodeList.push_front(tagSLRouteNode(pMountPoints[tmpindex].node,0));
        }
        else
        {
            pBaseNodeList.push_front(tagSLRouteNode(pMountPoints[tmpindex].node,1));
            break;
        }
    }

    return pBaseNodeList;
}

/// 打印进路条件
void WNodeManager::printSect(const tagRouteCondiItem* routecondiitem)
{
    if(routecondiitem == NULL) return;

    wxString tmpStr = " 敌对信号灯:";
    for(int i=0;i<routecondiitem->conflictsignals.size();i++)
        tmpStr += wxString::Format("%s,",routecondiitem->conflictsignals[i]->getName());
    wxString tmpStr2 = " 敌对道岔:";
    for(int i=0;i<routecondiitem->conflictswitch.size();i++)
        tmpStr2 += wxString::Format("%s:%d,",routecondiitem->conflictswitch[i].switchnode->getName(),
                                    routecondiitem->conflictswitch[i].switchstate);
    wxString tmpStr3 = " 带动道岔:";
    for(int i=0;i<routecondiitem->followswitch.size();i++)
        tmpStr3 += wxString::Format("%s:%d,",routecondiitem->followswitch[i].switchnode->getName(),
                                    routecondiitem->followswitch[i].switchstate);

    CMainFrame::getSingleton().printlog(LOG_LEVEL_INFO,
                                        wxString::Format(wxT("进路条件:%s-%s %s %s %s"),
                                                         routecondiitem->startLight,routecondiitem->endLight,
                                                         tmpStr,tmpStr2,tmpStr3).ToUTF8());
}

/// 检测两个结点之间进路的有效性
const tagRouteCondiItem* WNodeManager::checkRoute(wxString startNode,wxString endNode)
{
    return CRouteConditions::getSingleton().getRouteCondiItem(startNode,endNode);
}

/// 得到指定设备ID的区段
tagSectNode* WNodeManager::getSectByDeviceID(int deviceid)
{
    if(deviceid <= 0 || mSects.empty())
        return NULL;

    std::map<wxString,tagSectNode*>::iterator iter = mSects.begin();
    for(;iter != mSects.end();++iter)
    {
        if((*iter).second->deviceID == deviceid)
            return (*iter).second;
    }

    return NULL;
}

/// 得到指定名称的区段
tagSectNode* WNodeManager::getSect(wxString sectName)
{
    if(sectName == "" || mSects.empty())
        return NULL;

    std::map<wxString,tagSectNode*>::iterator iter = mSects.find(sectName);
    if(iter == mSects.end())
        return NULL;

    return (*iter).second;
}

/// 得到指定的进路
tagRoute* WNodeManager::getSelectedRoute(wxString startLight,wxString endLight)
{
    if(startLight == "" || endLight == "")
        return NULL;

    std::map<wxString,std::map<wxString,tagRoute*>>::iterator iter = mRoutes.find(startLight);
    if(iter != mRoutes.end())
    {
        std::map<wxString,tagRoute*>::iterator iter2 = (*iter).second.find(endLight);
        if(iter2 != (*iter).second.end())
            return (*iter2).second;
    }

    return NULL;
}

/// 添加一条进路到系统中
tagRoute* WNodeManager::addRoute(wxString startLight,wxString endLight,wxVector<tagSLRouteNode> nodes)
{
    if(startLight == "" || endLight == "" || nodes.empty())
        return NULL;

    std::map<wxString,std::map<wxString,tagRoute*>>::iterator iter = mRoutes.find(startLight);
    if(iter != mRoutes.end())
    {
        std::map<wxString,tagRoute*>::iterator iter2 = (*iter).second.find(endLight);
        if(iter2 != (*iter).second.end())
            return (*iter2).second;
    }

    tagRoute *pRoute = new tagRoute();
    pRoute->startLight = startLight;
    pRoute->endLight = endLight;

    for(int i=0;i<nodes.size();i++)
        pRoute->sectNodes[nodes[i].sectName].push_back(nodes[i]);

    mRoutes[startLight][endLight] = pRoute;

    return mRoutes[startLight][endLight];
}

/// 自动清除进行中的进路
void WNodeManager::autoDeleteSelectedRoute(void)
{
    std::map<wxString,std::map<wxString,tagRoute*>>::iterator iter = mRoutes.begin();
    for(;iter != mRoutes.end();)
    {
        std::map<wxString,tagRoute*>::iterator iter2 = (*iter).second.begin();
        for(;iter2 != (*iter).second.end();)
        {
            bool isOk = true;
            for(int i=0;i<(*iter2).second->getAllSects().size();i++)
            {
                tagSectNode *pSect = this->getSect((*iter2).second->getAllSects()[i]);
                if(pSect && pSect->getSectOperState() != NodeOperState::NORMAL)
                {
                    isOk = false;
                    break;
                }
            }

            if(isOk)
                iter2 = (*iter).second.erase(iter2);
            else
                ++iter2;
        }

        if((*iter).second.empty())
            iter = mRoutes.erase(iter);
        else
            ++iter;
    }
}

/// 得到两个结点之间的进路
wxVector<tagSLRouteNode> WNodeManager::getRoute(wxString startNode,wxString endNode,bool isaddother)
{
    if((startNode == "" || endNode == "") || (startNode == endNode))
        return wxVector<tagSLRouteNode>();

    WBaseNode *pStartNode = this->getNodeByName(startNode);
    WBaseNode *pEndNode = this->getNodeByName(endNode);
    if(pStartNode == NULL || pEndNode == NULL)
        return wxVector<tagSLRouteNode>();

    bool isFinded = false;
    wxVector<tagSLRouteNode> resultRouteNodes;

    // 先从左往右搜索
    std::list<tagSLRouteNode> resultroutelist = this->searchRoute(pStartNode,
                                                                  pEndNode,
                                                                  DIRECTION_RIGHT);

    if(!resultroutelist.empty())
    {
        resultRouteNodes.assign(resultroutelist.rbegin(),resultroutelist.rend());
        isFinded = true;
    }

    if(!isFinded)
    {
        // 先从右往左搜索
        resultroutelist = this->searchRoute(pStartNode,
                                            pEndNode,
                                            DIRECTION_LEFT);

        if(!resultroutelist.empty())
            resultRouteNodes.assign(resultroutelist.rbegin(),resultroutelist.rend());
    }

    // 根据信号灯的设置选择是否带后面一条轨道
    if(isaddother && !resultRouteNodes.empty())
    {
        if(resultRouteNodes[resultRouteNodes.size()-1].node->getNodeType() == NodeType::NODE_SIGNAL)
        {
            WSignalLampNode *pWSignalLampNode = static_cast<WSignalLampNode*>(resultRouteNodes[resultRouteNodes.size()-1].node);
            if(pWSignalLampNode)
            {
                switch(pWSignalLampNode->getRouteType())
                {
                case SLRouteType::ROUTE_LEFT:
                {
                    wxVector<tagMountPoint> pmountpoints = pWSignalLampNode->getMountPointByDir(MountDirection::DIRECTION_LEFT);
                    if(pmountpoints.size() == 1)
                       resultRouteNodes.push_back(tagSLRouteNode(pmountpoints[0].node,1));
                }
                    break;
                case SLRouteType::ROUTE_RIGHT:
                {
                    wxVector<tagMountPoint> pmountpoints = pWSignalLampNode->getMountPointByDir(MountDirection::DIRECTION_RIGHT);
                    if(pmountpoints.size() == 1)
                       resultRouteNodes.push_back(tagSLRouteNode(pmountpoints[0].node,1));
                }
                    break;
                default:
                    break;
                }
            }
        }
    }

    int pStartPosition = 0;

    std::map<wxString,tagSectNode*>::iterator iterSect = mSects.begin();
    for(;iterSect != mSects.end();++iterSect)
    {
        int sectIndex = (*iterSect).second->isInSect(resultRouteNodes,&pStartPosition);
        if(sectIndex >= 0 && pStartPosition > 0)
        {
            for(int i=0;i<pStartPosition;i++)
            {
                resultRouteNodes[i].sectName = (*iterSect).first;
                resultRouteNodes[i].sectPosition = sectIndex;
            }
        }
    }

    return resultRouteNodes;
}

/// 处理鼠标事件
WBaseNode* WNodeManager::OnMMouseEvent(wxMouseEvent& event)
{
    if(mNodes.empty()) return NULL;

    wxMutexLocker locker(mNodeMutex);

    std::map<wxString,WBaseNode*>::iterator iter = mNodes.begin();
    for(;iter != mNodes.end();++iter)
    {
        if((*iter).second->OnMMouseEvent(event))
            return (*iter).second;
    }

    return NULL;
}

/// 得到所有的进行中的进路
wxVector<tagRoute*> WNodeManager::getAllRoutes(void)
{
    wxVector<tagRoute*> decRoutes;

    std::map<wxString,std::map<wxString,tagRoute*>>::iterator iter = mRoutes.begin();
    for(;iter != mRoutes.end();++iter)
    {
        std::map<wxString,tagRoute*>::iterator iter2 = (*iter).second.begin();
        for(;iter2 != (*iter).second.end();++iter2)
        {
            decRoutes.push_back((*iter2).second);
        }
    }

    return decRoutes;
}

/// 重置所有结点状态
void WNodeManager::resetAllNodes(void)
{
    if(mNodes.empty()) return;

    wxMutexLocker locker(mNodeMutex);

    std::map<wxString,WBaseNode*>::iterator iter = mNodes.begin();
    for(;iter != mNodes.end();++iter)
    {
        (*iter).second->reset();
    }
}
